﻿// VsPkg.cs : Implementation of WidgetspherePackage
//

using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE;

using Widgetsphere.Generator.Common.Util;

[assembly:ComVisible(true)]

namespace Widgetsphere.VsCodeTools
{
  /// <summary>
  /// This is the class that implements the package exposed by this assembly.
  ///
  /// The minimum requirement for a class to be considered a valid package for Visual Studio
  /// is to implement the IVsPackage interface and register itself with the shell.
  /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
  /// to do it: it derives from the Package class that provides the implementation of the 
  /// IVsPackage interface and uses the registration attributes defined in the framework to 
  /// register itself and its components with the shell.
  /// </summary>
  // This attribute tells the registration utility (regpkg.exe) that this class needs
  // to be registered as package.
  [PackageRegistration(UseManagedResourcesOnly = true)]
  // A Visual Studio component can be registered under different regitry roots; for instance
  // when you debug your package you want to register it in the experimental hive. This
  // attribute specifies the registry root to use if no one is provided to regpkg.exe with
  // the /root switch.
  [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\8.0exp")]
  // This attribute is used to register the informations needed to show the this package
  // in the Help/About dialog of Visual Studio.
  [InstalledProductRegistration(false, "#100", "#102", "1.0", IconResourceID = 400)]
  // In order be loaded inside Visual Studio in a machine that has not the VS SDK installed, 
  // package needs to have a valid load key (it can be requested at 
  // http://msdn.microsoft.com/vstudio/extend/). This attributes tells the shell that this 
  // package has a load key embedded in its resources.
  [ProvideLoadKey("Standard", "1.0", "VsCodeTools", "Widgetsphere", 1)]
  // This attribute is needed to let the shell know that this package exposes some menus.
  [ProvideMenuResource(1000, 1)]
	[ProvideEditorExtension(typeof(EditorFactory), ".mod", 50,
						ProjectGuid = "{2150E333-8FDC-42a3-9474-1A3956D46DE8}",
						TemplateDir = "..\\Wizard",
						NameResourceID = 106,
						DefaultName = "VsCodeTools")]
	[ProvideEditorLogicalView(typeof(EditorFactory), "{7651a703-06e5-11d1-8ebd-00a0c90f26ea}")]
	[Guid("B4ADADB2-BB95-413e-BDDD-F9A2046A2F9F")]
  public sealed class WidgetspherePackage : Package
  {

    private EditorFactory editorFactory;

    /// <summary>
    /// Default constructor of the package.
    /// Inside this method you can place any initialization code that does not require 
    /// any Visual Studio service because at this point the package object is created but 
    /// not sited yet inside Visual Studio environment. The place to do all the other 
    /// initialization is the Initialize method.
    /// </summary>
    public WidgetspherePackage()
    {
      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
    }



    /// <summary>
    /// Helper function that will load a resource string using the standard Visual Studio Resource Manager
    /// Service (SVsResourceManager). Because of the fact that it is using a service, this method can be
    /// called only after the package is sited.
    /// </summary>
    internal static string GetResourceString(string resourceName)
    {
      string resourceValue;
      IVsResourceManager resourceManager = (IVsResourceManager)GetGlobalService(typeof(SVsResourceManager));
      if (resourceManager == null)
      {
        throw new InvalidOperationException("Could not get SVsResourceManager service. Make sure the package is Sited before calling this method.");
      }
      Guid packageGuid = typeof(WidgetspherePackage).GUID;
      int hr = resourceManager.LoadResourceString(ref packageGuid, -1, resourceName, out resourceValue);
      Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(hr);
      return resourceValue;
    }
    internal static string GetResourceString(int resourceID)
    {
      return GetResourceString(string.Format("@{0}", resourceID));
    }

    /////////////////////////////////////////////////////////////////////////////
    // Overriden Package Implementation
    #region Package Members

    /// <summary>
    /// Initialization of the package; this method is called right after the package is sited, so this is the place
    /// where you can put all the initilaization code that rely on services provided by VisualStudio.
    /// </summary>
    protected override void Initialize()
    {
      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
      base.Initialize();

      //Create Editor Factory
      editorFactory = new EditorFactory(this);
      base.RegisterEditorFactory(editorFactory);

      // Add our command handlers for menu (commands must exist in the .ctc file)
      OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
      if (null != mcs)
      {
        // Create the command for the menu item.
        CommandID menuCommandID = new CommandID(GuidList.guidWidgetspherePackageCmdSet, (int)PkgCmdIDList.cmdParseAsp);
        MenuCommand menuItem = new MenuCommand(new EventHandler(MenuItemCallback), menuCommandID);
        mcs.AddCommand(menuItem);
      }
		
			//Set the DTE
			DTE dte = (DTE)GetService(typeof(DTE));
			EnvDTEHelper.Instance.SetDTE(dte);
		}

    #endregion

    private void MenuItemConfigureCallback(object sender, EventArgs e)
    {
      // Show a Message Box to prove we were here
      IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
      Guid clsid = Guid.Empty;
      int result;
      uiShell.ShowMessageBox(
                 0,
                 ref clsid,
                 "VsCodeTools",
                 string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.ToString()),
                 string.Empty,
                 0,
                 OLEMSGBUTTON.OLEMSGBUTTON_OK,
                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                 OLEMSGICON.OLEMSGICON_INFO,
                 0,        // false
                 out result);
    }

    /// <summary>
    /// This function is the callback used to execute a command when the a menu item is clicked.
    /// See the Initialize method to see how the menu item is associated to this function using
    /// the OleMenuCommandService service and the MenuCommand class.
    /// </summary>
    private void MenuItemCallback(object sender, EventArgs e)
    {
      EnvDTEHelper.Instance.ApplicationObject.UndoContext.Open("ParceAsp", true);
      try
      {
        TextSelection selection = (TextSelection)EnvDTEHelper.Instance.ApplicationObject.ActiveDocument.Selection;
        TextPoint endPoint = selection.BottomPoint;
        EditPoint editPoint = endPoint.CreateEditPoint();
        editPoint.EndOfLine();

        string output = AspStringBlock.ParceAsp(selection.Text);

        int startLine = editPoint.Line + 1;
        editPoint.Insert(output);
        selection.MoveToLineAndOffset(startLine, 1, false);
      }
      catch(Exception ex)
      {
				GlobalHelper.SetErr(ex);
        System.Diagnostics.Debug.WriteLine(ex.ToString());
      }
      finally
      {
        EnvDTEHelper.Instance.ApplicationObject.UndoContext.Close();
      }
    }
  }
}